package com.chen.facemanager.service.impl;


import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.chen.facemanager.bean.Sca;
import com.chen.facemanager.bean.WxOrder;
import com.chen.facemanager.dao.ScaDao;
import com.chen.facemanager.dao.WxOrderDao;
import com.chen.facemanager.service.WXservice;
import com.chen.facemanager.util.WXConfigUtil;
import com.chen.facemanager.util.WxMD5Util;
import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.transaction.Transactional;
import java.net.DatagramPacket;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
public class WXserviceImpl implements WXservice {
    private static final Logger logger = LoggerFactory.getLogger("WXserviceImpl");

//    public static final String GETWAY = "http://1o669531n3.imwork.net:42997/";
    public static final String SPBILL_CREATE_IP = "140.143.132.167";
    //    public static final String NOTIFY_URL = "http://chenyongpeng.xyz/weixin/notify";
//    public static final String NOTIFY_URL = GETWAY + "/weixin/notify";
//    public static final String NOTIFY_URL = "http://chenapp.free.idcfengye.com/weixin/notify";

    @Value("${CHEN.GETWAY}")
    private String GETWAY;

    @Value("${CHEN.NOTIFY_URL}")
    private String NOTIFY_URL;


    @Autowired
    private WxOrderDao wxOrderDao;

    @Autowired
    private ScaDao scaDao;

    @Override
    public Map<String, String> dounifiedOrder(String uid, String hid, String total_fee,String attach,String body,String type) throws Exception {
        System.out.println("回调地址："+NOTIFY_URL);
        WxMD5Util md5Util = new WxMD5Util();
        Map<String, String> returnMap = new HashMap<>();
        WXConfigUtil config = new WXConfigUtil();
        WXPay wxpay = new WXPay(config);
        Map<String, String> data = new HashMap<>();
        //生成商户订单号，不可重复
        String out_trade_no = "wxpay" + System.currentTimeMillis();

        data.put("appid", config.getAppID());
        data.put("mch_id", config.getMchID());
        data.put("nonce_str", WXPayUtil.generateNonceStr());
        data.put("body", body);
        data.put("out_trade_no", out_trade_no);
        data.put("total_fee", total_fee);
        //自己的服务器IP地址
        data.put("spbill_create_ip", SPBILL_CREATE_IP);
        //异步通知地址（请注意必须是外网）
        data.put("notify_url", NOTIFY_URL);
        //交易类型
        data.put("trade_type", "APP");
        //附加数据，在查询API和支付通知中原样返回，该字段主要用于商户携带订单的自定义数据
        data.put("attach", attach);
        data.put("sign_type","MD5");
        String sign1 = md5Util.getSign(data);
        data.put("sign", sign1);

        try {
            //使用官方API请求预付订单
            Map<String, String> response = wxpay.unifiedOrder(data);
            System.out.println("APP获取微信支付的响应："+response);
            String returnCode = response.get("return_code");    //获取返回码
            //若返回码为SUCCESS，则会返回一个result_code,再对该result_code进行判断
            if (returnCode.equals("SUCCESS")) {//主要返回以下5个参数
                String resultCode = response.get("result_code");
                returnMap.put("appid", response.get("appid"));
                returnMap.put("mch_id", response.get("mch_id"));
                returnMap.put("nonce_str", response.get("nonce_str"));
                returnMap.put("sign", response.get("sign"));
                if ("SUCCESS".equals(resultCode)) {//resultCode 为SUCCESS，才会返回prepay_id和trade_type
                    //获取预支付交易回话标志
                    returnMap.put("trade_type", response.get("trade_type"));
                    returnMap.put("prepay_id", response.get("prepay_id"));

                    // 生成订单
                    // 保存订单到自己数据库
                    wxOrderDao.save(new WxOrder(out_trade_no,response.get("prepay_id"),hid,uid,(System.currentTimeMillis() / 1000),Integer.parseInt(total_fee),100,1,type));
                    return returnMap;
                } else {
                    //此时返回没有预付订单的数据
                    return returnMap;
                }
            } else {
                return returnMap;
            }
        } catch (Exception e) {
            System.out.println("错误信息："+e);
            //系统等其他错误的时候
        }
        return returnMap;
    }

    @Override
    public Map<String, String> dounifiedOrderIOS(String uid, String hid, String total_fee,String attach,String body,String type) throws Exception {
        WxMD5Util md5Util = new WxMD5Util();
        Map<String, String> returnMap = new HashMap<>();
        WXConfigUtil config = new WXConfigUtil();
        WXPay wxpay = new WXPay(config);
        Map<String, String> data = new HashMap<>();
        String out_trade_no = "wxpay" + System.currentTimeMillis();

        data.put("appid", config.getAppID());
        data.put("mch_id", config.getMchID());
        data.put("nonce_str", WXPayUtil.generateNonceStr());
        data.put("body", body);
        data.put("out_trade_no", out_trade_no);
        data.put("total_fee", total_fee);
        //自己的服务器IP地址
        data.put("spbill_create_ip", SPBILL_CREATE_IP);
        //异步通知地址（请注意必须是外网）
        data.put("notify_url", NOTIFY_URL);
        //交易类型
        data.put("trade_type", "MWEB");
        data.put("scene_info","{\"h5_info\": {\"type\":\"IOS\",\"app_name\": \"市政通\",\"bundle_id\": \"com.hcr.elecident\"}}");
        //附加数据，在查询API和支付通知中原样返回，该字段主要用于商户携带订单的自定义数据
        data.put("attach", attach);
        data.put("sign_type","MD5");
        String sign1 = md5Util.getSign(data);
        data.put("sign", sign1);

        try {
            //使用官方API请求预付订单
            Map<String, String> response = wxpay.unifiedOrder(data);
            System.out.println("获取微信支付的响应："+response);
            String returnCode = response.get("return_code");    //获取返回码
            //若返回码为SUCCESS，则会返回一个result_code,再对该result_code进行判断
            if (returnCode.equals("SUCCESS")) {//主要返回以下5个参数
                String resultCode = response.get("result_code");
                returnMap.put("appid", response.get("appid"));
                returnMap.put("mch_id", response.get("mch_id"));
                returnMap.put("nonce_str", response.get("nonce_str"));
                returnMap.put("sign", response.get("sign"));
                if ("SUCCESS".equals(resultCode)) {//resultCode 为SUCCESS，才会返回prepay_id和trade_type
                    //获取预支付交易回话标志
                    returnMap.put("trade_type", response.get("trade_type"));
                    returnMap.put("prepay_id", response.get("prepay_id"));
                    returnMap.put("mweb_url",response.get("mweb_url"));
                    // 生成订单
                    // 保存订单到自己数据库
                    wxOrderDao.save(new WxOrder(out_trade_no,response.get("prepay_id"),hid,uid,(System.currentTimeMillis() / 1000),Integer.parseInt(total_fee),100,1,type));

                    return returnMap;
                } else {
                    //此时返回没有预付订单的数据
                    return returnMap;
                }
            } else {
                return returnMap;
            }
        } catch (Exception e) {
            System.out.println("错误信息："+e);
            //系统等其他错误的时候
        }
        return returnMap;
    }

    /**
     *
     * @param notifyData 异步通知后的XML数据
     * @return
     */
    @Override
    @Transactional
    public String payBack(String notifyData) {
        WXConfigUtil config = null;
        try {
            config = new WXConfigUtil();
        } catch (Exception e) {
            e.printStackTrace();
        }
        WXPay wxpay = new WXPay(config);
        String xmlBack = "";
        Map<String, String> notifyMap = null;
        try {
            notifyMap = WXPayUtil.xmlToMap(notifyData);         // 调用官方SDK转换成map类型数据
            if (wxpay.isPayResultNotifySignatureValid(notifyMap)) {//验证签名是否有效，有效则进一步处理

                String return_code = notifyMap.get("return_code");//状态
                String out_trade_no = notifyMap.get("out_trade_no");//商户订单号
                if (return_code.equals("SUCCESS")) {
                    if (out_trade_no != null) {

                        String attach = notifyMap.get("attach");
                        if (attach != "" || attach != null){
                            if (attach.substring(0,1).equals("a")){
                                String[] att = attach.split(",");
                                Sca s = new Sca(att[1],att[2],att[3],0,"","");
                                System.out.println("身份核验支付成功回调附加数据："+s.toString());
                                scaDao.save(s);
                            }
                            if (attach.substring(0,1).equals("b")){
                                String[] att = attach.split(",");
                                Map<String, Object> map = new HashMap<>();
                                map.put("name", att[1]);
                                map.put("idnumber", att[2]);
                                map.put("terminalid", att[3]);
                                map.put("uid", att[4]);

                                JSONObject jsonObject = JSONUtil.parseObj(map);

                                String s = HttpUtil.post(GETWAY+"service/jsz",jsonObject.toString());
                                System.out.println("驾驶证核验支付成功回调附加数据："+s.toString());
                            }
                        }

                        wxOrderDao.updateByOrderid(out_trade_no);

                        System.err.println("支付成功");

                        logger.info("微信手机支付回调成功订单号:{}", out_trade_no);
                        xmlBack = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>" + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
                    } else {
                        logger.info("微信手机支付回调失败订单号:{}", out_trade_no);
                        xmlBack = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
                    }
                }
                return xmlBack;
            } else {
                // 签名错误，如果数据里没有sign字段，也认为是签名错误
                //失败的数据要不要存储？
                logger.error("手机支付回调通知签名错误");
                xmlBack = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
                return xmlBack;
            }
        } catch (Exception e) {
            logger.error("手机支付回调通知失败", e);
            xmlBack = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
        }
        return xmlBack;
    }
}